/*
	wxTradePost - A TradePost Calculator for Guild Wars 2
	Copyright (C) 2012 Scorcher24 <scorcher24@gmail.com>

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "project.hpp"
#include "Mainframe.hpp"
#include "Application.hpp"

const float TP_LISTING_FEE = 0.05f;
const float TP_SELLING_FEE = 0.10f;

BEGIN_EVENT_TABLE(Mainframe, wxFrame)
	EVT_BUTTON(XRCID("btnReset"), Mainframe::OnResetInput)
    EVT_BUTTON(XRCID("btnCalc"),  Mainframe::OnCalc)
    EVT_BUTTON(XRCID("btnAbout"), Mainframe::OnAbout)
    EVT_CHECKBOX(XRCID("chkAlwaysOnTop"), Mainframe::OnAlwaysOnTop)
END_EVENT_TABLE()

Mainframe::Mainframe()
: wxFrame(NULL, -1, "wxTradePostCalculator for Guild Wars 2 by Scorcher24", wxDefaultPosition, wxSize(515, 357), 
		  wxFRAME_TOOL_WINDOW | wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
{
	// Load Panel from XRC 
	wxXmlResource::Get()->LoadPanel(this, "MainPanel");

	// Create validator
	wxTextValidator numericValidator(wxFILTER_INCLUDE_CHAR_LIST);

	wxArrayString list;
	wxString valid_chars(wxT("0123456789"));
	size_t len = valid_chars.Length();
	for (size_t i=0; i<len; i++){
		list.Add(wxString(valid_chars.GetChar(i))); 
	}
	numericValidator.SetIncludes(list); 

	// Get pointers to the widgets
	m_buy_gold   = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtBuyGold")));
	m_buy_silver = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtBuySilver")));
	m_buy_copper = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtBuyCopper")));

	m_sell_gold   = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtSellGold")));
	m_sell_silver = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtSellSilver")));
	m_sell_copper = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtSellCopper")));

	m_quantity    = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtQuantity")));

	m_revenue	  = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtRevenue")));
	m_cost		  = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtCost")));
	m_listing_fee = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtListingFee")));
	m_selling_fee  = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtSaleFee")));
	m_profit	  = dynamic_cast<wxTextCtrl*>(wxWindow::FindWindow(XRCID("txtProfit")));

	// Apply validators
	m_buy_gold->SetValidator(numericValidator);
	m_buy_silver->SetValidator(numericValidator);
	m_buy_copper->SetValidator(numericValidator);

	m_sell_gold->SetValidator(numericValidator);
	m_sell_silver->SetValidator(numericValidator);
	m_sell_copper->SetValidator(numericValidator);

	m_quantity->SetValidator(numericValidator);
}

Mainframe::~Mainframe()
{

}

void Mainframe::OnResetInput( wxCommandEvent& )
{
	m_buy_copper->SetValue("0");
	m_buy_silver->SetValue("0");
	m_buy_gold->SetValue("0");

	m_sell_gold->SetValue("0");
	m_sell_silver->SetValue("0");
	m_sell_copper->SetValue("0");

    m_quantity->SetValue("1");
}

void Mainframe::OnAbout( wxCommandEvent& )
{
    wxAboutDialogInfo info;
    info.SetName(_("wxTradePost"));
    info.SetVersion(_("Version 1 Revision 6"));
    info.SetDescription(_("TradePost Calculator for Guild Wars 2"));
    info.SetCopyright(_T("(C) 2012 under GPL V3 by Scorcher24 <scorcher24@gmail.com>"));

    wxAboutBox(info);
}

void Mainframe::OnCalc( wxCommandEvent& )
{
	// Variables 
	long sell_price = 0;
	long buy_price  = 0;
	long quantity   = 0;
    long cost       = 0;
    long sell_fee   = 0;
    long list_fee   = 0;

	m_quantity->GetValue().ToLong(&quantity);

	// Get buying values
	{
		long gold = 0;
		long silver = 0;
		long copper = 0;

		m_buy_gold->GetValue().ToLong(&gold);
		m_buy_silver->GetValue().ToLong(&silver);
		m_buy_copper->GetValue().ToLong(&copper);

		buy_price = (( gold * 10000 ) + ( silver * 100 ) + ( copper )) * quantity;

        int cost_gold = buy_price / 10000;
        int cost_silver = (buy_price - ( cost_gold * 10000 ) ) / 100;
        int cost_copper = (buy_price - ( cost_gold * 10000 ) - ( cost_silver * 100 )) / 10 ;

        std::stringstream ss;
        ss << cost_gold << "G " << cost_silver << "S " << cost_copper << "C ";
        m_cost->SetValue(ss.str());
	}

	// Get selling values
	{
		long gold = 0;
		long silver = 0;
		long copper = 0;

		m_sell_gold->GetValue().ToLong(&gold);
		m_sell_silver->GetValue().ToLong(&silver);
		m_sell_copper->GetValue().ToLong(&copper);

		sell_price = (( gold * 10000 ) + ( silver * 100 ) + ( copper )) * quantity;

        int sell_gold = sell_price / 10000;
        int sell_silver = (sell_price - ( sell_gold * 10000 ) ) / 100;
        int sell_copper = (sell_price - ( sell_gold * 10000 ) - ( sell_silver * 100 )) / 10 ;

        std::stringstream ss;
        ss << sell_gold << "G " << sell_silver << "S " << sell_copper << "C ";
        m_revenue->SetValue(ss.str());
	}

    // Calculate listing fee
    {
	    list_fee = sell_price * TP_LISTING_FEE;	

        int list_gold = list_fee / 10000;
        int list_silver = (list_fee - ( list_gold * 10000 ) ) / 100;
        int list_copper = (list_fee - ( list_gold * 10000 ) - ( list_silver * 100 )) / 10 ;

        std::stringstream ss;
        ss << list_gold << "G " << list_silver << "S " << list_copper << "C";
        m_listing_fee->SetValue(ss.str());
    }

    // Calculate selling fee
    {
        sell_fee = sell_price * TP_SELLING_FEE;

        int sell_gold   = sell_fee / 10000;
        int sell_silver = (sell_fee - ( sell_gold * 10000 ) ) / 100;
        int sell_copper = (sell_fee - ( sell_gold * 10000 ) - ( sell_silver * 100 )) / 10;

        std::stringstream ss;
        ss << sell_gold << "G " << sell_silver << "S " << sell_copper << "C";
        m_selling_fee->SetValue(ss.str());
    }          
    //Calculate profit
    {
        int profit = sell_price - buy_price - sell_fee - list_fee;

        int profit_gold = profit / 10000;
        int profit_silver = (profit - ( profit_gold * 10000 ) ) / 100;
        int profit_copper = (profit - ( profit_gold * 10000 ) - ( profit_silver * 100 )) / 10 ;

        std::stringstream ss;
        ss << profit_gold << "G " << profit_silver << "S " << profit_copper << "C";
        m_profit->SetValue(ss.str());
        
        // Color Background if we are in profit or debt
        if ( profit_gold < 0 || profit_silver < 0 || profit_copper < 0 ){
            m_profit->SetBackgroundColour(*wxRED);
        }
        else{
            m_profit->SetBackgroundColour(*wxGREEN);
        }

    }
}

void Mainframe::OnAlwaysOnTop( wxCommandEvent& e )
{
    if ( e.IsChecked() ){
        long style = this->GetWindowStyle();
        style |= wxSTAY_ON_TOP;
        this->SetWindowStyle(style);
    }
    else{
        long style = this->GetWindowStyle();
        style &= ~wxSTAY_ON_TOP;
        this->SetWindowStyle(style);
    }
}